<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>运算符表达式</title>
        
        


        <!-- Custom HTML head -->
        


        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        
        <link rel="icon" href="../favicon.svg">
        
        
        <link rel="shortcut icon" href="../favicon.png">
        
        <link rel="stylesheet" href="../css/variables.css">
        <link rel="stylesheet" href="../css/general.css">
        <link rel="stylesheet" href="../css/chrome.css">
        <link rel="stylesheet" href="../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
        
        <link rel="stylesheet" href="../fonts/fonts.css">
        

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../highlight.css">
        <link rel="stylesheet" href="../tomorrow-night.css">
        <link rel="stylesheet" href="../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        
        <link rel="stylesheet" href="../theme/reference.css">
        

        
    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded affix "><a href="../翻译说明.html">翻译说明</a></li><li class="chapter-item expanded affix "><a href="../introduction.html">介绍</a></li><li class="chapter-item expanded "><a href="../notation.html"><strong aria-hidden="true">1.</strong> 表义符</a></li><li class="chapter-item expanded "><a href="../lexical-structure.html"><strong aria-hidden="true">2.</strong> 词法结构</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../input-format.html"><strong aria-hidden="true">2.1.</strong> 输入格式</a></li><li class="chapter-item expanded "><a href="../keywords.html"><strong aria-hidden="true">2.2.</strong> 关键字</a></li><li class="chapter-item expanded "><a href="../identifiers.html"><strong aria-hidden="true">2.3.</strong> 标识符</a></li><li class="chapter-item expanded "><a href="../comments.html"><strong aria-hidden="true">2.4.</strong> 注释</a></li><li class="chapter-item expanded "><a href="../whitespace.html"><strong aria-hidden="true">2.5.</strong> 空白符</a></li><li class="chapter-item expanded "><a href="../tokens.html"><strong aria-hidden="true">2.6.</strong> token</a></li></ol></li><li class="chapter-item expanded "><a href="../macros.html"><strong aria-hidden="true">3.</strong> 宏</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../macros-by-example.html"><strong aria-hidden="true">3.1.</strong> 声明宏</a></li><li class="chapter-item expanded "><a href="../procedural-macros.html"><strong aria-hidden="true">3.2.</strong> 过程宏</a></li></ol></li><li class="chapter-item expanded "><a href="../crates-and-source-files.html"><strong aria-hidden="true">4.</strong> crate 和源文件</a></li><li class="chapter-item expanded "><a href="../conditional-compilation.html"><strong aria-hidden="true">5.</strong> 条件编译</a></li><li class="chapter-item expanded "><a href="../items.html"><strong aria-hidden="true">6.</strong> 程序项</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../items/modules.html"><strong aria-hidden="true">6.1.</strong> 模块</a></li><li class="chapter-item expanded "><a href="../items/extern-crates.html"><strong aria-hidden="true">6.2.</strong> 外部crate</a></li><li class="chapter-item expanded "><a href="../items/use-declarations.html"><strong aria-hidden="true">6.3.</strong> use声明</a></li><li class="chapter-item expanded "><a href="../items/functions.html"><strong aria-hidden="true">6.4.</strong> 函数</a></li><li class="chapter-item expanded "><a href="../items/type-aliases.html"><strong aria-hidden="true">6.5.</strong> 类型别名</a></li><li class="chapter-item expanded "><a href="../items/structs.html"><strong aria-hidden="true">6.6.</strong> 结构体</a></li><li class="chapter-item expanded "><a href="../items/enumerations.html"><strong aria-hidden="true">6.7.</strong> 枚举</a></li><li class="chapter-item expanded "><a href="../items/unions.html"><strong aria-hidden="true">6.8.</strong> 联合体</a></li><li class="chapter-item expanded "><a href="../items/constant-items.html"><strong aria-hidden="true">6.9.</strong> 常量项</a></li><li class="chapter-item expanded "><a href="../items/static-items.html"><strong aria-hidden="true">6.10.</strong> 静态项</a></li><li class="chapter-item expanded "><a href="../items/traits.html"><strong aria-hidden="true">6.11.</strong> trait</a></li><li class="chapter-item expanded "><a href="../items/implementations.html"><strong aria-hidden="true">6.12.</strong> 实现</a></li><li class="chapter-item expanded "><a href="../items/external-blocks.html"><strong aria-hidden="true">6.13.</strong> 外部块</a></li><li class="chapter-item expanded "><a href="../items/generics.html"><strong aria-hidden="true">6.14.</strong> 泛型参数</a></li><li class="chapter-item expanded "><a href="../items/associated-items.html"><strong aria-hidden="true">6.15.</strong> 关联程序项</a></li></ol></li><li class="chapter-item expanded "><a href="../attributes.html"><strong aria-hidden="true">7.</strong> 属性</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../attributes/testing.html"><strong aria-hidden="true">7.1.</strong> 测试</a></li><li class="chapter-item expanded "><a href="../attributes/derive.html"><strong aria-hidden="true">7.2.</strong> 派生</a></li><li class="chapter-item expanded "><a href="../attributes/diagnostics.html"><strong aria-hidden="true">7.3.</strong> 诊断</a></li><li class="chapter-item expanded "><a href="../attributes/codegen.html"><strong aria-hidden="true">7.4.</strong> 代码生成</a></li><li class="chapter-item expanded "><a href="../attributes/limits.html"><strong aria-hidden="true">7.5.</strong> 极限值设置</a></li><li class="chapter-item expanded "><a href="../attributes/type_system.html"><strong aria-hidden="true">7.6.</strong> 类型系统</a></li></ol></li><li class="chapter-item expanded "><a href="../statements-and-expressions.html"><strong aria-hidden="true">8.</strong> 语句和表达式</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../statements.html"><strong aria-hidden="true">8.1.</strong> 语句</a></li><li class="chapter-item expanded "><a href="../expressions.html"><strong aria-hidden="true">8.2.</strong> 表达式</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../expressions/literal-expr.html"><strong aria-hidden="true">8.2.1.</strong> 字面量表达式</a></li><li class="chapter-item expanded "><a href="../expressions/path-expr.html"><strong aria-hidden="true">8.2.2.</strong> 路径表达式</a></li><li class="chapter-item expanded "><a href="../expressions/block-expr.html"><strong aria-hidden="true">8.2.3.</strong> 块表达式</a></li><li class="chapter-item expanded "><a href="../expressions/operator-expr.html" class="active"><strong aria-hidden="true">8.2.4.</strong> 运算符表达式</a></li><li class="chapter-item expanded "><a href="../expressions/grouped-expr.html"><strong aria-hidden="true">8.2.5.</strong> 分组表达式</a></li><li class="chapter-item expanded "><a href="../expressions/array-expr.html"><strong aria-hidden="true">8.2.6.</strong> 数组和索引表达式</a></li><li class="chapter-item expanded "><a href="../expressions/tuple-expr.html"><strong aria-hidden="true">8.2.7.</strong> 元组和索引表达式</a></li><li class="chapter-item expanded "><a href="../expressions/struct-expr.html"><strong aria-hidden="true">8.2.8.</strong> 结构体表达式</a></li><li class="chapter-item expanded "><a href="../expressions/call-expr.html"><strong aria-hidden="true">8.2.9.</strong> 调用表达式</a></li><li class="chapter-item expanded "><a href="../expressions/method-call-expr.html"><strong aria-hidden="true">8.2.10.</strong> 方法调用表达式</a></li><li class="chapter-item expanded "><a href="../expressions/field-expr.html"><strong aria-hidden="true">8.2.11.</strong> 字段访问表达式</a></li><li class="chapter-item expanded "><a href="../expressions/closure-expr.html"><strong aria-hidden="true">8.2.12.</strong> 闭包表达式</a></li><li class="chapter-item expanded "><a href="../expressions/loop-expr.html"><strong aria-hidden="true">8.2.13.</strong> 循环表达式</a></li><li class="chapter-item expanded "><a href="../expressions/range-expr.html"><strong aria-hidden="true">8.2.14.</strong> 区间表达式</a></li><li class="chapter-item expanded "><a href="../expressions/if-expr.html"><strong aria-hidden="true">8.2.15.</strong> if 和 if let 表达式</a></li><li class="chapter-item expanded "><a href="../expressions/match-expr.html"><strong aria-hidden="true">8.2.16.</strong> 匹配表达式</a></li><li class="chapter-item expanded "><a href="../expressions/return-expr.html"><strong aria-hidden="true">8.2.17.</strong> 返回表达式</a></li><li class="chapter-item expanded "><a href="../expressions/await-expr.html"><strong aria-hidden="true">8.2.18.</strong> 等待(await)表达式</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../patterns.html"><strong aria-hidden="true">9.</strong> 模式</a></li><li class="chapter-item expanded "><a href="../type-system.html"><strong aria-hidden="true">10.</strong> 类型系统</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../types.html"><strong aria-hidden="true">10.1.</strong> 类型</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../types/boolean.html"><strong aria-hidden="true">10.1.1.</strong> 布尔型</a></li><li class="chapter-item expanded "><a href="../types/numeric.html"><strong aria-hidden="true">10.1.2.</strong> 数字型</a></li><li class="chapter-item expanded "><a href="../types/textual.html"><strong aria-hidden="true">10.1.3.</strong> 字符型</a></li><li class="chapter-item expanded "><a href="../types/never.html"><strong aria-hidden="true">10.1.4.</strong> never类型</a></li><li class="chapter-item expanded "><a href="../types/tuple.html"><strong aria-hidden="true">10.1.5.</strong> 元组</a></li><li class="chapter-item expanded "><a href="../types/array.html"><strong aria-hidden="true">10.1.6.</strong> 数组</a></li><li class="chapter-item expanded "><a href="../types/slice.html"><strong aria-hidden="true">10.1.7.</strong> 切片</a></li><li class="chapter-item expanded "><a href="../types/struct.html"><strong aria-hidden="true">10.1.8.</strong> 结构体</a></li><li class="chapter-item expanded "><a href="../types/enum.html"><strong aria-hidden="true">10.1.9.</strong> 枚举</a></li><li class="chapter-item expanded "><a href="../types/union.html"><strong aria-hidden="true">10.1.10.</strong> 联合体</a></li><li class="chapter-item expanded "><a href="../types/function-item.html"><strong aria-hidden="true">10.1.11.</strong> 函数项类型</a></li><li class="chapter-item expanded "><a href="../types/closure.html"><strong aria-hidden="true">10.1.12.</strong> 闭包</a></li><li class="chapter-item expanded "><a href="../types/pointer.html"><strong aria-hidden="true">10.1.13.</strong> 指针型</a></li><li class="chapter-item expanded "><a href="../types/function-pointer.html"><strong aria-hidden="true">10.1.14.</strong> 函数指针</a></li><li class="chapter-item expanded "><a href="../types/trait-object.html"><strong aria-hidden="true">10.1.15.</strong> trait对象</a></li><li class="chapter-item expanded "><a href="../types/impl-trait.html"><strong aria-hidden="true">10.1.16.</strong> 实现trait</a></li><li class="chapter-item expanded "><a href="../types/parameters.html"><strong aria-hidden="true">10.1.17.</strong> 类型参数</a></li><li class="chapter-item expanded "><a href="../types/inferred.html"><strong aria-hidden="true">10.1.18.</strong> 推断型</a></li></ol></li><li class="chapter-item expanded "><a href="../dynamically-sized-types.html"><strong aria-hidden="true">10.2.</strong> 动态尺寸类型(DST)</a></li><li class="chapter-item expanded "><a href="../type-layout.html"><strong aria-hidden="true">10.3.</strong> 类型布局 </a></li><li class="chapter-item expanded "><a href="../interior-mutability.html"><strong aria-hidden="true">10.4.</strong> 内部可变性</a></li><li class="chapter-item expanded "><a href="../subtyping.html"><strong aria-hidden="true">10.5.</strong> 子类型和型变</a></li><li class="chapter-item expanded "><a href="../trait-bounds.html"><strong aria-hidden="true">10.6.</strong> trait约束及其生存期约束</a></li><li class="chapter-item expanded "><a href="../type-coercions.html"><strong aria-hidden="true">10.7.</strong> 类型自动强转</a></li><li class="chapter-item expanded "><a href="../destructors.html"><strong aria-hidden="true">10.8.</strong> 析构函数</a></li><li class="chapter-item expanded "><a href="../lifetime-elision.html"><strong aria-hidden="true">10.9.</strong> 生存期省略</a></li></ol></li><li class="chapter-item expanded "><a href="../special-types-and-traits.html"><strong aria-hidden="true">11.</strong> 特殊类型和 trait</a></li><li class="chapter-item expanded "><a href="../names.html"><strong aria-hidden="true">12.</strong> 名称</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../names/namespaces.html"><strong aria-hidden="true">12.1.</strong> 命名空间</a></li><li class="chapter-item expanded "><a href="../names/scopes.html"><strong aria-hidden="true">12.2.</strong> 作用域</a></li><li class="chapter-item expanded "><a href="../names/preludes.html"><strong aria-hidden="true">12.3.</strong> 预导入包</a></li><li class="chapter-item expanded "><a href="../paths.html"><strong aria-hidden="true">12.4.</strong> 路径</a></li><li class="chapter-item expanded "><a href="../names/name-resolution.html"><strong aria-hidden="true">12.5.</strong> 名称解析</a></li><li class="chapter-item expanded "><a href="../visibility-and-privacy.html"><strong aria-hidden="true">12.6.</strong> 可见性与隐私权</a></li></ol></li><li class="chapter-item expanded "><a href="../memory-model.html"><strong aria-hidden="true">13.</strong> 内存模型</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../memory-allocation-and-lifetime.html"><strong aria-hidden="true">13.1.</strong> 内存分配和生存期</a></li><li class="chapter-item expanded "><a href="../variables.html"><strong aria-hidden="true">13.2.</strong> 变量</a></li></ol></li><li class="chapter-item expanded "><a href="../linkage.html"><strong aria-hidden="true">14.</strong> 链接(linkage)</a></li><li class="chapter-item expanded "><a href="../unsafety.html"><strong aria-hidden="true">15.</strong> 非安全性</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../unsafe-functions.html"><strong aria-hidden="true">15.1.</strong> 非安全函数</a></li><li class="chapter-item expanded "><a href="../unsafe-blocks.html"><strong aria-hidden="true">15.2.</strong> 非安全代码块</a></li><li class="chapter-item expanded "><a href="../behavior-considered-undefined.html"><strong aria-hidden="true">15.3.</strong> 未定义行为</a></li><li class="chapter-item expanded "><a href="../behavior-not-considered-unsafe.html"><strong aria-hidden="true">15.4.</strong> 不被认为是非安全的行为</a></li></ol></li><li class="chapter-item expanded "><a href="../const_eval.html"><strong aria-hidden="true">16.</strong> 常量求值</a></li><li class="chapter-item expanded "><a href="../abi.html"><strong aria-hidden="true">17.</strong> ABI</a></li><li class="chapter-item expanded "><a href="../runtime.html"><strong aria-hidden="true">18.</strong> Rust运行时</a></li><li class="chapter-item expanded "><a href="../appendices.html"><strong aria-hidden="true">19.</strong> 附录</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../macro-ambiguity.html"><strong aria-hidden="true">19.1.</strong> 宏定义规范</a></li><li class="chapter-item expanded "><a href="../influences.html"><strong aria-hidden="true">19.2.</strong> 影响来源</a></li><li class="chapter-item expanded "><a href="../glossary.html"><strong aria-hidden="true">19.3.</strong> 术语表</a></li><li class="chapter-item expanded "><a href="../本书术语翻译对照表.html"><strong aria-hidden="true">19.4.</strong> 本书术语翻译对照表</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                
                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                        
                    </div>

                    <h1 class="menu-title"></h1>

                    <div class="right-buttons">
                        <a href="../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>
                        
                        <a href="https://gitee.com/minstrel1977/rust-reference" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>
                        
                    </div>
                </div>

                
                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>
                

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1><a class="header" href="#操作符运算符表达式" id="操作符运算符表达式">操作符/运算符表达式</a></h1>
<h1><a class="header" href="#operator-expressions" id="operator-expressions">Operator expressions</a></h1>
<blockquote>
<p><a href="https://github.com/rust-lang/reference/blob/master/src/expressions/operator-expr.md">operator-expr.md</a><br />
commit: 0b7f340e8963eccac662f97cb679855f043a658f <br />
本章译文最后维护日期：2021-07-17</p>
</blockquote>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>OperatorExpression</em> :<br />
      <a href="#borrow-operators"><em>BorrowExpression</em></a><br />
   | <a href="#the-dereference-operator"><em>DereferenceExpression</em></a><br />
   | <a href="#the-question-mark-operator"><em>ErrorPropagationExpression</em></a><br />
   | <a href="#negation-operators"><em>NegationExpression</em></a><br />
   | <a href="#arithmetic-and-logical-binary-operators"><em>ArithmeticOrLogicalExpression</em></a><br />
   | <a href="#comparison-operators"><em>ComparisonExpression</em></a><br />
   | <a href="#lazy-boolean-operators"><em>LazyBooleanExpression</em></a><br />
   | <a href="#type-cast-expressions"><em>TypeCastExpression</em></a><br />
   | <a href="#assignment-expressions"><em>AssignmentExpression</em></a><br />
   | <a href="#compound-assignment-expressions"><em>CompoundAssignmentExpression</em></a></p>
</blockquote>
<p>操作符是 Rust 语言为其内建类型定义的。
本文后面的许多操作符都可以使用 <code>std::ops</code> 或 <code>std::cmp</code> 中的 trait 进行重载。</p>
<h2><a class="header" href="#溢出" id="溢出">溢出</a></h2>
<h2><a class="header" href="#overflow" id="overflow">Overflow</a></h2>
<p>在 debug模式下编译整数运算时，如果发生溢出，会触发 panic。
可以使用命令行参数 <code>-C debug-assertions</code> 和 <code>-C overflow-checks</code> 设置编译器标志位来更直接地控制这个溢出过程。
以下情况被认为是溢出：</p>
<ul>
<li>当 <code>+</code>、<code>*</code> 或 <code>-</code> 创建的值大于当前类型可存储的最大值或小于最小值。这包括任何有符号整型的最小值上的一元运算符 <code>-</code>。</li>
<li>使用 <code>/</code> 或 <code>%</code>，其中左操作数是某类有符号整型的最小整数，右操作数是 <code>-1</code>。注意，即使由于历史原因禁用了 <code>-C overflow-checks</code>选项，这些检查仍会发生。</li>
<li>使用 <code>&lt;&lt;</code> 或 <code>&gt;&gt;</code>，其中右操作数大于或等于左操作数类型的 bit 数，或右操作数为负数。</li>
</ul>
<h2><a class="header" href="#借用操作符运算符" id="借用操作符运算符">借用操作符/运算符</a></h2>
<h2><a class="header" href="#borrow-operators" id="borrow-operators">Borrow operators</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>BorrowExpression</em> :<br />
      (<code>&amp;</code>|<code>&amp;&amp;</code>) <a href="../expressions.html"><em>Expression</em></a><br />
   | (<code>&amp;</code>|<code>&amp;&amp;</code>) <code>mut</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p><code>&amp;</code>（共享借用）和 <code>&amp;mut</code>（可变借用）运算符是一元前缀运算符。
当应用于<a href="../expressions.html#place-expressions-and-value-expressions">位置表达式</a>上时，此表达式生成指向值所在的内存位置的引用（指针）。
在引用存续期间，该内存位置也被置于借出状态。
对于共享借用（<code>&amp;</code>），这意味着该位置可能不会发生变化，但可能会被再次读取或共享。
对于可变借用（<code>&amp;mut</code>），在借用到期之前，不能以任何方式访问该位置。<code>&amp;mut</code> 在可变位置表达式上下文中会对其操作数求值。
如果 <code>&amp;</code> 或 <code>&amp;mut</code> 运算符应用于<a href="../expressions.html#place-expressions-and-value-expressions">值表达式</a>上，则会创建一个<a href="../expressions.html#temporaries">临时值</a>。</p>
<p>这类操作符不能重载。</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>{
    // 将创建一个存值为7的临时位置，该该临时位置在此作用域内持续存在
    let shared_reference = &amp;7;
}
let mut array = [-2, 3, 9];
{
    // 在当前作用域内可变借用了 `array`。那 `array` 就只能通过 `mutable_reference` 来使用。
    let mutable_reference = &amp;mut array;
}
<span class="boring">}
</span></code></pre></pre>
<p>尽管 <code>&amp;&amp;</code> 是一个单一 token（<a href="#lazy-boolean-operators">惰性与(<code>and</code>)操作符</a>)，但在借用表达式(borrow expressions)上下文中使用时，它是作为两个借用操作符用的：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// 意义相同：
let a = &amp;&amp;  10;
let a = &amp; &amp; 10;

// 意义相同：
let a = &amp;&amp;&amp;&amp;  mut 10;
let a = &amp;&amp; &amp;&amp; mut 10;
let a = &amp; &amp; &amp; &amp; mut 10;
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#解引用操作符" id="解引用操作符">解引用操作符</a></h2>
<h2><a class="header" href="#the-dereference-operator" id="the-dereference-operator">The dereference operator</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>DereferenceExpression</em> :<br />
   <code>*</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p><code>*</code>（解引用）操作符也是一元前缀操作符。当应用于<a href="../types/pointer.html">指针</a>上时，它表示该指针指向的内存位置。
如果表达式的类型为 <code>&amp;mut T</code> 或 <code>*mut T</code>，并且该表达式是局部变量、局部变量的（内嵌）字段、或是可变的<a href="../expressions.html#place-expressions-and-value-expressions">位置表达式</a>，则它代表的内存位置可以被赋值。解引用原始指针需要在非安全(<code>unsafe</code>)块才能进行。</p>
<p>在<a href="../expressions.html#mutability">不可变位置表达式上下文</a>中对非指针类型作 <code>*x</code> 相当于执行 <code>*std::ops::Deref::deref(&amp;x)</code>；同样的，在可变位置表达式上下文中这个动作就相当于执行 <code>*std::ops::DerefMut::deref_mut(&amp;mut x)</code>。</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let x = &amp;7;
assert_eq!(*x, 7);
let y = &amp;mut 9;
*y = 11;
assert_eq!(*y, 11);
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#问号操作符" id="问号操作符">问号操作符</a></h2>
<h2><a class="header" href="#the-question-mark-operator" id="the-question-mark-operator">The question mark operator</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>ErrorPropagationExpression</em> :<br />
   <a href="../expressions.html"><em>Expression</em></a> <code>?</code></p>
</blockquote>
<p>问号操作符（<code>?</code>）解包(unwrap)有效值或返回错误值，并将它们传播(propagate)给调用函数。
问号操作符（<code>?</code>）是一个一元后缀操作符，只能应用于类型 <code>Result&lt;T, E&gt;</code> 和 <code>Option&lt;T&gt;</code>。</p>
<p>当应用在 <code>Result&lt;T, E&gt;</code> 类型的值上时，它可以传播错误。
如果值是 <code>Err(e)</code>，那么它实际上将从此操作符所在的函数体或闭包中返回 <code>Err(From::from(e))</code>。
如果应用到 <code>Ok(x)</code>，那么它将解包此值以求得 <code>x</code>。</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">use std::num::ParseIntError;
</span>fn try_to_parse() -&gt; Result&lt;i32, ParseIntError&gt; {
    let x: i32 = &quot;123&quot;.parse()?; // x = 123
    let y: i32 = &quot;24a&quot;.parse()?; // 立即返回一个 Err()
    Ok(x + y)                    // 不会执行到这里
}

let res = try_to_parse();
println!(&quot;{:?}&quot;, res);
<span class="boring">assert!(res.is_err())
</span><span class="boring">}
</span></code></pre></pre>
<p>当应用到 <code>Option&lt;T&gt;</code> 类型的值时，它向调用者传播错误 <code>None</code>。
如果它应用的值是 <code>None</code>，那么它将返回 <code>None</code>。
如果应用的值是 <code>Some(x)</code>，那么它将解包此值以求得 <code>x</code>。</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn try_option_some() -&gt; Option&lt;u8&gt; {
    let val = Some(1)?;
    Some(val)
}
assert_eq!(try_option_some(), Some(1));

fn try_option_none() -&gt; Option&lt;u8&gt; {
    let val = None?;
    Some(val)
}
assert_eq!(try_option_none(), None);
<span class="boring">}
</span></code></pre></pre>
<p>操作符 <code>?</code> 不能被重载。</p>
<h2><a class="header" href="#取反运算符" id="取反运算符">取反运算符</a></h2>
<h2><a class="header" href="#negation-operators" id="negation-operators">Negation operators</a></h2>
<blockquote>
<p><strong><sup>语法</sup></strong><br />
<em>NegationExpression</em> :<br />
      <code>-</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <code>!</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p>这是最后两个一元运算符。
下表总结了它们用在基本类型上的表现，同时指出其他类型要重载这些操作符需要实现的 trait。
记住，有符号整数总是用二进制补码形式表示。
所有这些运算符的操作数都在<a href="../expressions.html#place-expressions-and-value-expressions">值表达式上下文</a>中被求值，所以这些操作数的值会被移走或复制。</p>
<table><thead><tr><th>符号</th><th>整数</th><th><code>bool</code></th><th>浮点数</th><th>用于重载的 trait</th></tr></thead><tbody>
<tr><td><code>-</code></td><td>符号取反*</td><td></td><td>符号取反</td><td><code>std::ops::Neg</code></td></tr>
<tr><td><code>!</code></td><td>按位取反</td><td><a href="../types/boolean.html#logical-not">逻辑非</a></td><td></td><td><code>std::ops::Not</code></td></tr>
</tbody></table>
<p>* 仅适用于有符号整数类型。</p>
<p>下面是这些运算符的一些示例：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let x = 6;
assert_eq!(-x, -6);
assert_eq!(!x, -7);
assert_eq!(true, !false);
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#算术和逻辑二元运算符" id="算术和逻辑二元运算符">算术和逻辑二元运算符</a></h2>
<h2><a class="header" href="#arithmetic-and-logical-binary-operators" id="arithmetic-and-logical-binary-operators">Arithmetic and Logical Binary Operators</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>ArithmeticOrLogicalExpression</em> :<br />
      <a href="../expressions.html"><em>Expression</em></a> <code>+</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>-</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>*</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>/</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>%</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&amp;</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>|</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>^</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&lt;&lt;</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&gt;&gt;</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p>二元运算符表达式都用中缀表示法(infix notation)书写。
下表总结了算术和逻辑二元运算符在原生类型(primitive type)上的行为，同时指出其他类型要重载这些操作符需要实现的 trait。
记住，有符号整数总是用二进制补码形式表示。
所有这些运算符的操作数都在<a href="../expressions.html#place-expressions-and-value-expressions">值表达式上下文</a>中求值，因此这些操作数的值会被移走或复制。</p>
<table><thead><tr><th>符号</th><th>整数</th><th><code>bool</code></th><th>浮点数</th><th>用于重载此运算符的 trait</th><th>用于重载此运算符的复合赋值(Compound Assignment) Trait</th></tr></thead><tbody>
<tr><td><code>+</code></td><td>加法</td><td></td><td>加法</td><td><code>std::ops::Add</code></td><td><code>std::ops::AddAssign</code></td></tr>
<tr><td><code>-</code></td><td>减法</td><td></td><td>减法</td><td><code>std::ops::Sub</code></td><td><code>std::ops::SubAssign</code></td></tr>
<tr><td><code>*</code></td><td>乘法</td><td></td><td>乘法</td><td><code>std::ops::Mul</code></td><td><code>std::ops::MulAssign</code></td></tr>
<tr><td><code>/</code></td><td>除法*</td><td></td><td>取余</td><td><code>std::ops::Div</code></td><td><code>std::ops::DivAssign</code></td></tr>
<tr><td><code>%</code></td><td>取余**</td><td></td><td>Remainder</td><td><code>std::ops::Rem</code></td><td><code>std::ops::RemAssign</code></td></tr>
<tr><td><code>&amp;</code></td><td>按位与</td><td><a href="../types/boolean.html#logical-and">逻辑与</a></td><td></td><td><code>std::ops::BitAnd</code></td><td><code>std::ops::BitAndAssign</code></td></tr>
<tr><td><code>|</code></td><td>按位或</td><td><a href="../types/boolean.html#logical-or">逻辑或</a></td><td></td><td><code>std::ops::BitOr</code></td><td><code>std::ops::BitOrAssign</code></td></tr>
<tr><td><code>^</code></td><td>按位异或</td><td><a href="../types/boolean.html#logical-xor">逻辑异或</a></td><td></td><td><code>std::ops::BitXor</code></td><td><code>std::ops::BitXorAssign</code></td></tr>
<tr><td><code>&lt;&lt;</code></td><td>左移位</td><td></td><td></td><td><code>std::ops::Shl</code></td><td><code>std::ops::ShlAssign</code></td></tr>
<tr><td><code>&gt;&gt;</code></td><td>右移位***</td><td></td><td></td><td><code>std::ops::Shr</code></td><td><code>std::ops::ShrAssign</code></td></tr>
</tbody></table>
<p>* 整数除法趋零取整。</p>
<p>** Rust使用由<a href="https://en.wikipedia.org/wiki/Modulo_operation#Variants_of_the_definition">截断除法</a>定义的求宇运算。也就是 <code>余数=被除数%除数</code>，其中余数将与被除数的符号一致。</p>
<p>*** 有符号整数类型算术右移位，无符号整数类型逻辑右移位。</p>
<p>下面是使用这些操作符的示例:</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>assert_eq!(3 + 6, 9);
assert_eq!(5.5 - 1.25, 4.25);
assert_eq!(-5 * 14, -70);
assert_eq!(14 / 3, 4);
assert_eq!(100 % 7, 2);
assert_eq!(0b1010 &amp; 0b1100, 0b1000);
assert_eq!(0b1010 | 0b1100, 0b1110);
assert_eq!(0b1010 ^ 0b1100, 0b110);
assert_eq!(13 &lt;&lt; 3, 104);
assert_eq!(-10 &gt;&gt; 2, -3);
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#比较运算符" id="比较运算符">比较运算符</a></h2>
<h2><a class="header" href="#comparison-operators" id="comparison-operators">Comparison Operators</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>ComparisonExpression</em> :<br />
      <a href="../expressions.html"><em>Expression</em></a> <code>==</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>!=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&gt;</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&lt;</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&gt;=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&lt;=</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p>Rust 还为原生类型以及标准库中的多种类型都定义了比较运算符。
链式比较运算时需要借助圆括号，例如，表达式 <code>a == b == c</code> 是无效的，（但如果逻辑允许）可以写成 <code>(a == b) == c</code>。</p>
<p>与算术运算符和逻辑运算符不同，重载这些运算符的 trait 通常用于显示/约定如何比较一个类型，并且还很可能会假定使用这些 trait 作为约束条件的函数定义了实际的比较逻辑。
其实标准库中的许多函数和宏都使用了这个假定（尽管不能确保这些假定的安全性）。
与上面的算术和逻辑运算符不同，这些运算符会隐式地对它们的操作数执行共享借用，并在<a href="../expressions.html#place-expressions-and-value-expressions">位置表达式上下文</a>中对它们进行求值：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">let a = 1;
</span><span class="boring">let b = 1;
</span>a == b;
// 等价于：
::std::cmp::PartialEq::eq(&amp;a, &amp;b);
<span class="boring">}
</span></code></pre></pre>
<p>这意味着不需要将值从操作数移出(moved out of)。</p>
<table><thead><tr><th>符号</th><th>含义</th><th>须重载方法</th></tr></thead><tbody>
<tr><td><code>==</code></td><td>等于</td><td><code>std::cmp::PartialEq::eq</code></td></tr>
<tr><td><code>!=</code></td><td>不等于</td><td><code>std::cmp::PartialEq::ne</code></td></tr>
<tr><td><code>&gt;</code></td><td>大于</td><td><code>std::cmp::PartialOrd::gt</code></td></tr>
<tr><td><code>&lt;</code></td><td>小于</td><td><code>std::cmp::PartialOrd::lt</code></td></tr>
<tr><td><code>&gt;=</code></td><td>大于或等于</td><td><code>std::cmp::PartialOrd::ge</code></td></tr>
<tr><td><code>&lt;=</code></td><td>小于或等于</td><td><code>std::cmp::PartialOrd::le</code></td></tr>
</tbody></table>
<p>下面是使用比较运算符的示例：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>assert!(123 == 123);
assert!(23 != -12);
assert!(12.5 &gt; 12.2);
assert!([1, 2, 3] &lt; [1, 3, 4]);
assert!('A' &lt;= 'B');
assert!(&quot;World&quot; &gt;= &quot;Hello&quot;);
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#短路布尔运算符" id="短路布尔运算符">短路布尔运算符</a></h2>
<h2><a class="header" href="#lazy-boolean-operators" id="lazy-boolean-operators">Lazy boolean operators</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>LazyBooleanExpression</em> :<br />
      <a href="../expressions.html"><em>Expression</em></a> <code>||</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&amp;&amp;</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p>运算符 <code>||</code> 和 <code>&amp;&amp;</code> 可以应用在布尔类型的操作数上。
运算符 <code>||</code> 表示逻辑“或”，运算符 <code>&amp;&amp;</code> 表示逻辑“与”。
它们与 <code>|</code> 和 <code>&amp;</code> 的不同之处在于，只有在左操作数尚未确定表达式的结果时，才计算右操作数。
也就是说，<code>||</code> 只在左操作数的计算结果为 <code>false</code> 时才计算其右操作数，而只有在计算结果为 <code>true</code> 时才计算 <code>&amp;&amp;</code> 的操作数。</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let x = false || true; // true
let y = false &amp;&amp; panic!(); // false, 不会计算 `panic!()`
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#类型转换表达式" id="类型转换表达式">类型转换表达式</a></h2>
<h2><a class="header" href="#type-cast-expressions" id="type-cast-expressions">Type cast expressions</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>TypeCastExpression</em> :<br />
   <a href="../expressions.html"><em>Expression</em></a> <code>as</code> <a href="../types.html#type-expressions"><em>TypeNoBounds</em></a></p>
</blockquote>
<p>类型转换表达式用二元运算符 <code>as</code> 表示。</p>
<p>执行类型转换(<code>as</code>)表达式将左侧的值显式转换为右侧的类型。</p>
<p>类型转换(<code>as</code>)表达式的一个例子：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">fn sum(values: &amp;[f64]) -&gt; f64 { 0.0 }
</span><span class="boring">fn len(values: &amp;[f64]) -&gt; i32 { 0 }
</span>fn average(values: &amp;[f64]) -&gt; f64 {
    let sum: f64 = sum(values);
    let size: f64 = len(values) as f64;
    sum / size
}
<span class="boring">}
</span></code></pre></pre>
<p><code>as</code> 可用于显式执行<a href="../type-coercions.html">自动强转(coercions)</a>，以及下列形式的强制转换。
任何不符合强转规则或不在下表中的转换都会导致编译器报错。
下表中 <code>*T</code> 代表 <code>*const T</code> 或 <code>*mut T</code>。<code>m</code> 引用类型中代表可选的 <code>mut</code> 或指针类型中的 <code>mut</code> 或 <code>const</code>。</p>
<table><thead><tr><th><code>e</code> 的类型</th><th><code>U</code></th><th>通过 <code>e as U</code> 执行转换</th></tr></thead><tbody>
<tr><td>整型或浮点型</td><td>整型或浮点型</td><td>数字转换</td></tr>
<tr><td>类C(C-like)枚举</td><td>整型</td><td>枚举转换</td></tr>
<tr><td><code>bool</code> 或 <code>char</code></td><td>整型</td><td>原生类型到整型的转换</td></tr>
<tr><td><code>u8</code></td><td><code>char</code></td><td><code>u8</code> 到 <code>char</code> 的转换</td></tr>
<tr><td><code>*T</code></td><td><code>*V</code> where <code>V: Sized</code> *</td><td>指针到指针的转换</td></tr>
<tr><td><code>*T</code> where <code>T: Sized</code></td><td>数字型(Numeric type)</td><td>指针到地址的转换</td></tr>
<tr><td>整型</td><td><code>*V</code> where <code>V: Sized</code></td><td>地址到指针的转换</td></tr>
<tr><td><code>&amp;m₁ T</code></td><td><code>*m₂ T</code> **</td><td>引用到指针的转换</td></tr>
<tr><td><code>&amp;m₁ [T; n]</code></td><td><code>*m₂ T</code> **</td><td>数组到指针的转换</td></tr>
<tr><td><a href="../types/function-item.html">函数项</a></td><td><a href="../types/function-pointer.html">函数指针</a></td><td>函数到函数指针的转换</td></tr>
<tr><td><a href="../types/function-item.html">函数项</a></td><td><code>*V</code> where <code>V: Sized</code></td><td>函数到指针的转换</td></tr>
<tr><td><a href="../types/function-item.html">函数项</a></td><td>整型</td><td>函数到地址的转换</td></tr>
<tr><td><a href="../types/function-pointer.html">函数指针</a></td><td><code>*V</code> where <code>V: Sized</code></td><td>函数指针到指针的转换</td></tr>
<tr><td><a href="../types/function-pointer.html">函数指针</a></td><td>整型</td><td>函数指针到地址的转换</td></tr>
<tr><td>闭包 ***</td><td>函数指针</td><td>闭包到函数指针的转换</td></tr>
</tbody></table>
<p>* 或者 <code>T</code>和<code>V</code> 也可以都是兼容的 unsized 类型，例如，两个都是切片，或者都是同一种 trait对象。</p>
<p>** 仅当 <code>m₁</code> 是 <code>mut</code> 或 <code>m₂</code> 是 <code>const</code>时， 可变(<code>mut</code>)引用到 <code>const</code>指针才会被允许。</p>
<p>*** 仅适用于不捕获（遮蔽(close over)）任何环境变量的闭包。</p>
<h3><a class="header" href="#语义" id="语义">语义</a></h3>
<h3><a class="header" href="#semantics" id="semantics">Semantics</a></h3>
<h4><a class="header" href="#数字转换" id="数字转换">数字转换</a></h4>
<h4><a class="header" href="#numeric-cast" id="numeric-cast">Numeric cast</a></h4>
<ul>
<li>在两个尺寸(size)相同的整型数值（例如 i32 -&gt; u32）之间进行转换是一个空操作(no-op) （Rust 使用2的补码表示定长整数的负值）</li>
<li>从一个较大尺寸的整型转换为较小尺寸的整型（例如 u32 -&gt; u8）将会采用截断(truncate)算法 <sup class="footnote-reference"><a href="#译者注">1</a></sup></li>
<li>从较小尺寸的整型转换为较大尺寸的整型（例如 u8 -&gt; u32）将
<ul>
<li>如果源数据是无符号的，则进行零扩展(zero-extend)</li>
<li>如果源数据是有符号的，则进行符号扩展(sign-extend)</li>
</ul>
</li>
<li>从浮点数转换为整型将使浮点数趋零取整(round the float towards zero)
<ul>
<li><code>NaN</code> 将返回 <code>0</code></li>
<li>大于转换到的整型类型的最大值时（包括 <code>INFINITY</code>），取该整型类型的最大值。</li>
<li>小于转换到的整型类型的最小值时（包括 <code>INFINITY</code>），取该整型类型的最小值。</li>
</ul>
</li>
<li>从整数强制转换为浮点数将产生最接近的浮点数 *
<ul>
<li>如有必要，舍入采用 <code>roundTiesToEven</code>模式 ***</li>
<li>在溢出时，将会产生该浮点型的常量 Infinity(∞)（与输入符号相同）</li>
<li>注意：对于当前的数值类型集，溢出只会发生在 <code>u128 as f32</code> 这种转换形式，且数字大于或等于 <code>f32::MAX + (0.5 ULP)</code> 时。</li>
</ul>
</li>
<li>从 f32 到 f64 的转换是无损转换</li>
<li>从 f64 到 f32 的转换将产生最接近的 f32 **
<ul>
<li>如有必要，舍入采用 <code>roundTiesToEven</code>模式 ***</li>
<li>在溢出时，将会产生 f32 的常量 Infinity(∞)（与输入符号相同）
* 如果硬件本身不支持这种舍入模式和溢出行为，那么这些整数到浮点型的转换可能会比预期的要慢。</li>
</ul>
</li>
</ul>
<p>** 如果硬件本身不支持这种舍入模式和溢出行为，那么这些 f64 到 f32 的转换可能会比预期的要慢。</p>
<p>*** 按照 IEEE 754-2008§4.3.1 的定义：选择最接近的浮点数，如果恰好在两个浮点数中间，则优先选择最低有效位为偶数的那个。</p>
<h4><a class="header" href="#enum-cast" id="enum-cast">Enum cast</a></h4>
<h4><a class="header" href="#枚举转换" id="枚举转换">枚举转换</a></h4>
<p>可将枚举类型转换为其判别值，然后在必要时可以使用数字类型转换。</p>
<h4><a class="header" href="#primitive-to-integer-cast" id="primitive-to-integer-cast">Primitive to integer cast</a></h4>
<h4><a class="header" href="#原生类型到整型" id="原生类型到整型">原生类型到整型</a></h4>
<ul>
<li><code>false</code> 转换为 <code>0</code>，<code>true</code> 转换为 <code>1</code>。</li>
<li><code>char</code> 转换为字符码点，然后在必要时可以使用数字类型转换。</li>
</ul>
<h4><a class="header" href="#u8-to-char-cast" id="u8-to-char-cast"><code>u8</code> to <code>char</code> cast</a></h4>
<h4><a class="header" href="#u8-到-char" id="u8-到-char"><code>u8</code> 到 <code>char</code></a></h4>
<p>把为 <code>char</code> 的字符代码点的 <code>u8</code> 值转换为 <code>char</code></p>
<h4><a class="header" href="#pointer-to-address-cast" id="pointer-to-address-cast">Pointer to address cast</a></h4>
<h4><a class="header" href="#指针到地址" id="指针到地址">指针到地址</a></h4>
<p>把原始指针转换为整数将产生此指针指向的内存的机器地址。
如果被转换出的整数类型尺寸小于指针类型的位宽，地址可能会被截断；可以使用类型 <code>usize</code> 来避免这种情况。</p>
<h4><a class="header" href="#address-to-pointer-cast" id="address-to-pointer-cast">Address to pointer cast</a></h4>
<h4><a class="header" href="#地址到指针" id="地址到指针">地址到指针</a></h4>
<p>从整数转换为原始指针会将整数解释为内存地址，并生成一个引用该内存地址的指针。</p>
<div class="warning">
<p>警告：
这将与 Rust内存模型交互，需要指出的是该模型仍在开发中。
即便是按位转换后是一个有效的指针，但这种从转换中生成的指针可能会受到一些额外的限制。如果不遵循别名规则，那么解引用这样的指针可能是<a href="../behavior-considered-undefined.html">未定义行为</a>。</p>
</div>
<p>一个常见的健壮的地址转换算法的示例：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut values: [i32; 2] = [1, 2];
let p1: *mut i32 = values.as_mut_ptr();
let first_address = p1 as usize;
let second_address = first_address + 4; // 4 == size_of::&lt;i32&gt;()
let p2 = second_address as *mut i32;
unsafe {
    *p2 += 1;
}
assert_eq!(values[1], 3);
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#赋值表达式" id="赋值表达式">赋值表达式</a></h2>
<h2><a class="header" href="#assignment-expressions" id="assignment-expressions">Assignment expressions</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>AssignmentExpression</em> :<br />
   <a href="../expressions.html"><em>Expression</em></a> <code>=</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p><em>赋值表达式</em>会把某个值移入到一个特定的位置。</p>
<p><em>赋值表达式</em>由一个<a href="../expressions.html#mutability">可变</a> <a href="../expressions.html#place-expressions-and-value-expressions">位置表达式</a>（就是<em>被赋值的位置操作数</em>）后跟等号（<code>=</code>）和<a href="../expressions.html#place-expressions-and-value-expressions">值表达式</a>（就是被赋值的值操作数）组成。</p>
<p>与其他位置操作数不同，赋值位置操作数必须是一个位置表达式。
试图使用值表达式将导致编译器报错，而不是将其提升转换为临时位置。</p>
<p>赋值表达式要先计算它的操作数。
赋值的值操作数先被求值，然后是赋值的位置操作数。</p>
<blockquote>
<p><strong>注意</strong>：此表达式与其他表达式的求值顺序不同，此表达式的右操作数在左操作数之前被求值。</p>
</blockquote>
<p>对赋值表达的位置表达式求值时会先<a href="../destructors.html">销毁(drop)</a>此位置（如果是未初始化的局部变量或未初始化的局部变量的字段则不会启动这步析构操作），然后将赋值值<a href="../expressions.html#moved-and-copied-types">复制(copy)或移动(move)</a>到此位置中。</p>
<p>赋值表达式总是会生成<a href="../types/tuple.html">单元类型值</a>。</p>
<p>示例：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut x = 0;
let y = 0;
x = y;
<span class="boring">}
</span></code></pre></pre>
<h2><a class="header" href="#复合赋值表达式" id="复合赋值表达式">复合赋值表达式</a></h2>
<h2><a class="header" href="#compound-assignment-expressions" id="compound-assignment-expressions">Compound assignment expressions</a></h2>
<blockquote>
<p><strong><sup>句法</sup></strong><br />
<em>CompoundAssignmentExpression</em> :<br />
      <a href="../expressions.html"><em>Expression</em></a> <code>+=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>-=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>*=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>/=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>%=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&amp;=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>|=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>^=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&lt;&lt;=</code> <a href="../expressions.html"><em>Expression</em></a><br />
   | <a href="../expressions.html"><em>Expression</em></a> <code>&gt;&gt;=</code> <a href="../expressions.html"><em>Expression</em></a></p>
</blockquote>
<p><em>复合赋值表达式</em>将算术符（以及二进制逻辑操作符）与赋值表达式相结合在一起使用。</p>
<p>比如：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut x = 5;
x += 1;
assert!(x == 6);
<span class="boring">}
</span></code></pre></pre>
<p>复合赋值的句法是<a href="../expressions.html#mutability">可变</a> <a href="../expressions.html#place-expressions-and-value-expressions">位置表达式</a>（<em>被赋值操作数</em>），然后是一个操作符再后跟一个 <code>=</code>（这两个符号共同作为一个单独的 token），最后是一个<a href="../expressions.html#place-expressions-and-value-expressions">值表达式</a>（也叫被复合修改操作数(modifying operand)）。</p>
<p>与其他位置操作数不同，被赋值的位置操作数必须是一个位置表达式。
试图使用值表达式将导致编译器报错，而不是将其提升转换为临时位置。</p>
<p>复合赋值表达式的求值取决于操作符的类型。</p>
<p>如果复合赋值表达式了两个操作数的类型都是原生类型，则首先对被复合修改操作数进行求值，然后再对被赋值操作数求值。
最后将被赋值操作数的位置值设置为原被赋值操作数的值和复合修改操作数执行运算后的值。</p>
<blockquote>
<p><strong>注意</strong>：此表达式与其他表达式的求值顺序不同，此表达式的右操作数在左操作数之前被求值。</p>
</blockquote>
<p>此外，这个表达式是调用操作符重载复合赋值trait 的函数的语法糖（见本章前面的表格）。
被赋值操作数必须是可变的。</p>
<p>例如，下面 <code>example</code>函数中的两个表达式语句是等价的：</p>
<pre><pre class="playground"><code class="language-rust edition2018">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">struct Addable;
</span><span class="boring">use std::ops::AddAssign;
</span>
impl AddAssign&lt;Addable&gt; for Addable {
    /* */
<span class="boring">fn add_assign(&amp;mut self, other: Addable) {}
</span>}

fn example() {
<span class="boring">let (mut a1, a2) = (Addable, Addable);
</span>  a1 += a2;

<span class="boring">let (mut a1, a2) = (Addable, Addable);
</span>  AddAssign::add_assign(&amp;mut a1, a2);
}
<span class="boring">}
</span></code></pre></pre>
<p>与赋值表达式一样，复合赋值表达式也总是会生成<a href="../types/tuple.html">单元类型值</a>。</p>
<div class="warning">
<p>警告：复合赋值表达式的操作数的求值顺序取决于操作数的类型：对于原生类型，右边操作数将首先被求值，而对于非原生类型，左边操作数将首先被求值。
建议尽量不要编写依赖于复合赋值表达式中操作数的求值顺序的代码。请参阅<a href="https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs">这里的测试</a>以获得使用此依赖项的示例。</p>
</div>
<div class="footnote-definition" id="译者注"><sup class="footnote-definition-label">1</sup>
<p>截断，即一个值范围较大的变量A转换为值范围较小的变量B，如果超出范围，则将A减去B的区间长度。例如，128超出了i8类型的范围（-128,127），截断之后的值等于128-256=-128。</p>
</div>
<!-- 上面这几个链接从原文来替换时需小心 -->

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                        
                            <a rel="prev" href="../expressions/block-expr.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>
                        

                        
                            <a rel="next" href="../expressions/grouped-expr.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>
                        

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                
                    <a rel="prev" href="../expressions/block-expr.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
                    <a rel="next" href="../expressions/grouped-expr.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
                
            </nav>

        </div>

        

        

        

        
        <script type="text/javascript">
            window.playground_copyable = true;
        </script>
        

        

        
        <script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
        

        <script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->
        

        

    </body>
</html>
